pub mod validation;
pub mod auth;
use salvo::prelude::*;
use std::time::Instant;
use std::sync::atomic::{AtomicBool, Ordering};
use tokio::signal;
use tracing;

// 全局关闭状态
static SHUTDOWN_REQUESTED: AtomicBool = AtomicBool::new(false);

/// 启动信号监听任务
pub async fn setup_signal_handler() {
    tokio::spawn(async {
        #[cfg(unix)]
        {
            let mut sigterm = signal::unix::signal(signal::unix::SignalKind::terminate())
                .expect("Failed to install SIGTERM handler");
            let mut sigint = signal::unix::signal(signal::unix::SignalKind::interrupt())
                .expect("Failed to install SIGINT handler");
            
            tokio::select! {
                _ = sigterm.recv() => {
                    tracing::warn!("收到 SIGTERM 信号，开始优雅关闭");
                    SHUTDOWN_REQUESTED.store(true, Ordering::SeqCst);
                }
                _ = sigint.recv() => {
                    tracing::warn!("收到 SIGINT 信号，开始优雅关闭");
                    SHUTDOWN_REQUESTED.store(true, Ordering::SeqCst);
                }
            }
        }
        
        #[cfg(windows)]
        {
            let _ = signal::ctrl_c().await;
            tracing::warn!("收到 Ctrl+C 信号，开始优雅关闭");
            SHUTDOWN_REQUESTED.store(true, Ordering::SeqCst);
        }
    });
}

/// 手动触发关闭状态（可以从外部调用）
pub fn request_shutdown() {
    tracing::warn!("手动触发服务器关闭状态");
    SHUTDOWN_REQUESTED.store(true, Ordering::SeqCst);
}

/// 检查是否已请求关闭
pub fn is_shutdown_requested() -> bool {
    SHUTDOWN_REQUESTED.load(Ordering::SeqCst)
}

#[derive(Default)]
pub struct LogMiddleware;
#[async_trait]
impl Handler for LogMiddleware {
    async fn handle(
        &self,
        req: &mut Request,
        depot: &mut Depot,
        res: &mut Response,
        ctrl: &mut FlowCtrl,
    ) {
        let start_time = Instant::now();
        let client_addr = req.remote_addr().to_string();
        let path = req.uri().path().to_string();
        let method = req.method().to_string();

        tracing::info!(
            "{method} {path} << {client_addr}",
        );

        // 检查是否已请求关闭
        if is_shutdown_requested() {
            tracing::warn!(
                "服务器正在关闭，拒绝请求: {method} {path} from {client_addr}"
            );
            res.status_code(StatusCode::SERVICE_UNAVAILABLE);
            res.render("Service is shutting down");
            return;
        }

        ctrl.call_next(req, depot, res).await;

        let duration = start_time.elapsed();
        tracing::info!(
            "{client_addr} >> {duration:?}",
        );
    }
}